if on edge, bounce
if on edge, bounce
CategoryMotion
TypeCommand

if on edge, bounce is a command block and a motion block. It first checks if the sprite is touching the edge, and if it is, the sprite "bounces" off the edge by turning the sprite away.

if on edge, bounce::motion

Example Uses

Bouncing a sprite around the stage:

when green flag clicked
go to x: (0) y: (0)
point in direction (45 v)
forever {
  move (2) steps
  if on edge, bounce
}

Definition

This default definition can be found in Snap! 10.0 with Blocks all the way on. Remove or delete the block immediately after the definition hat if you want the script to be in action.


{if touching edge, bounce :: motion} :: define+
<t> primitive [bounceOffEdge V] :: other
if <touching [edge V] ?> {
  script variables ((get bounds)) ((bounds)) ((center)) ((stage bounds)) ((dir x)) ((dir y)) ((delta x)) ((delta y)) @delInput @addInput
  set [get bounds V] to ((list (minimum ((list (my [left V]) (my [bottom V]) @delInput @addInput) in front of (map ((list ([left V] of [ V]) ([bottom V] of [ V]) @delInput @addInput) @addInput) over (my [parts V])))) (maximum ((list (my [right V]) (my [top V]) @delInput @addInput) in front of (map ((list ([right V] of [ V]) ([top V] of [ V]) @delInput @addInput) @addInput) over (my [parts V])))) @delInput @addInput) @addInput)
  set [bounds V] to (call (get bounds) @verticalEllipsis @addInput)
  set [center V] to ((sum (bounds)) / (2))
  set [stage bounds V] to (ask (my [stage V]) for ((list (list (my [left V]) (my [bottom V]) @delInput @addInput) (list (my [right V]) (my [top V]) @delInput @addInput) @delInput @addInput) @addInput) @verticalEllipsis @addInput)
  set [dir x V] to ([sin V] of (direction))
  set [dir y V] to ([cos V] of (direction))
  if <(item (1 v) of (item (1 v) of (bounds))) < (item (1 v) of (item (1 v) of (stage bounds))) @delInput @verticalEllipsis @addInput> {
    set [dir x V] to ([abs V] of (dir x))
  } @addInput
  if <(item (1 v) of (item (2 v) of (bounds))) > (item (1 v) of (item (2 v) of (stage bounds))) @delInput @verticalEllipsis @addInput> {
    set [dir x V] to ([neg V] of ([abs V] of (dir x)))
  } @addInput
  if <(item (2 v) of (item (2 v) of (bounds))) > (item (2 v) of (item (2 v) of (stage bounds))) @delInput @verticalEllipsis @addInput> {
    set [dir y V] to ([neg V] of ([abs V] of (dir y)))
  } @addInput
  if <(item (2 v) of (item (1 v) of (bounds))) < (item (2 v) of (item (1 v) of (stage bounds))) @delInput @verticalEllipsis @addInput> {
    set [dir y V] to ([abs V] of (dir y))
  } @addInput
  point in direction (atan2 (dir x) / (dir y))
  set [bounds V] to (call (get bounds) @verticalEllipsis @addInput)
  go to ((position) + ((center) - ((sum (bounds)) / (2))) @delInput @verticalEllipsis @addInput)
  set [bounds V] to (call (get bounds) @verticalEllipsis @addInput)
  if <(item (1 v) of (item (2 v) of (bounds))) > (item (1 v) of (item (2 v) of (stage bounds))) @delInput @verticalEllipsis @addInput> {
    set [delta x V] to ((item (1 v) of (item (2 v) of (stage bounds))) - (item (1 v) of (item (2 v) of (bounds))))
  } @addInput
  if <(item (2 v) of (item (1 v) of (bounds))) < (item (2 v) of (item (1 v) of (stage bounds))) @delInput @verticalEllipsis @addInput> {
    set [delta y V] to ((item (2 v) of (item (1 v) of (stage bounds))) - (item (2 v) of (item (1 v) of (bounds))))
  } @addInput
  if <(item (1 v) of (item (1 v) of (bounds))) < (item (1 v) of (item (1 v) of (stage bounds))) @delInput @verticalEllipsis @addInput> {
    set [delta x V] to ((item (1 v) of (item (1 v) of (stage bounds))) - (item (1 v) of (item (1 v) of (bounds))))
  } @addInput
  if <(item (2 v) of (item (2 v) of (bounds))) > (item (2 v) of (item (2 v) of (stage bounds))) @delInput @verticalEllipsis @addInput> {
    set [delta y V] to ((item (2 v) of (item (2 v) of (stage bounds))) - (item (2 v) of (item (2 v) of (bounds))))
  } @addInput
  go to ((position) + (list (delta x) (delta y) @delInput @addInput) @delInput @verticalEllipsis @addInput)
} @addInput

See Also